/*
 * INSANE - Interactive Structural Analysis Environment
 *
 * Copyright (C) 2003-2006
 * Universidade Federal de Minas Gerais
 * Escola de Engenharia
 * Departamento de Engenharia de Estruturas
 *
 * Author's email :     insane@dees.ufmg.br
 * Author's Website :   http://www.dees.ufmg.br/insane
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */
 
package br.ufmg.dees.insane.draw;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Line2D;
import java.util.Vector;

/**
 * @author Fonseca, Flavio & Pitangueira, Roque
 * @since	April 2004
 */
public abstract class SpringDraw extends Draw {
	
//*****************************************************************************
	
	public static class Dx extends SpringDraw {
		
	//*****************************************************************************
		
		public Dx() {
			this( new Point(0, 0) );
		}
		
	//*****************************************************************************
		
		public Dx(Point loc) {
			this( loc, 0 );
		}
		
	//*****************************************************************************
		
		public Dx(Point loc, double theta) {
			this( loc, theta, null );
		}
		
	//*****************************************************************************
		
		public Dx(Point loc, double theta, Object represents) {
			this.setLocation(loc);
			this.setAngle(theta);
			this.setRepresents(represents);
			this.setSize(new Dimension(36, 24));
		}
		
	//*****************************************************************************
		
		public Vector<Object> getShapes() {
			
			Vector<Object> shapes = new Vector<Object>();
			
			int x = this.getLocation().x;
			int y = this.getLocation().y;
			int width = this.getSize().width;
			int height = this.getSize().height;
			double scale = this.getScale();
			
			double H = height * scale;
			double W = width * scale;
			
			shapes.add(new Line2D.Double( x, y, x+5*W/36, y ) );
			shapes.add(new Line2D.Double( x+5*W/36, y, x+7 *W/36, y-H/4) );
			shapes.add(new Line2D.Double( x+7 *W/36, y-H/4, x+11*W/36, y+H/4 ) );
			shapes.add(new Line2D.Double( x+11*W/36, y+H/4, x+15*W/36, y-H/4 ) );
			shapes.add(new Line2D.Double( x+15*W/36, y-H/4, x+19*W/36, y+H/4 ) );
			shapes.add(new Line2D.Double( x+19*W/36, y+H/4, x+23*W/36, y-H/4 ) );
			shapes.add(new Line2D.Double( x+23*W/36, y-H/4, x+27*W/36, y+H/4 ) );
			shapes.add(new Line2D.Double( x+27*W/36, y+H/4, x+29*W/36, y ) );
			shapes.add(new Line2D.Double( x+29*W/36, y, x+32*W/36, y ) );
			shapes.add(new Line2D.Double( x+32*W/36, y+H/2, x+32*W/36, y-H/2 ) );
			for(int i = 0; i < 6 ; i++)
				shapes.add(new Line2D.Double( x + 32*W/36, y + H/2 - (i+1)*(H/6), x + W , y + H/2 - i*(H/6)));
			
			return shapes;
		}
		
	//*****************************************************************************
		
		/**
		 * Returns the draw bounds in device units.
		 *
		 * @return the draw bounds
		 */
		 public Rectangle getBounds() {
			 
			 int x = this.getLocation().x;
			 int y = this.getLocation().y;
			 int width = this.getSize().width;
			 int height = this.getSize().height;
			 double scale = this.getScale();
			 
			 int W = (int)(width * scale);
			 int H = (int)(width * scale);
			 int h = (int)(height/6 * scale);
			 return new Rectangle((int)(x - W/2), y, W, H - h);
		 }
		 
	}
	
//*****************************************************************************
	
	public static class Dy extends SpringDraw {
		
	//*****************************************************************************
		
		public Dy() {
			this( new Point(0, 0) );
		}
		
	//*****************************************************************************
		
		public Dy(Point loc) {
			this( loc, 0 );
		}
		
	//*****************************************************************************
		
		public Dy(Point loc, double theta) {
			this( loc, theta, null );
		}
		
	//*****************************************************************************
		
		public Dy(Point loc, double theta, Object represents) {
			this.setLocation(loc);
			this.setAngle(theta);
			this.setRepresents(represents);
			this.setSize(new Dimension(24, 36));
		}
		
	//*****************************************************************************
		
		public Vector<Object> getShapes() {
			
			Vector<Object> shapes = new Vector<Object>();
			
			int x = this.getLocation().x;
			int y = this.getLocation().y;
			int width = this.getSize().width;
			int height = this.getSize().height;
			double scale = this.getScale();
			
			double H = height * scale;
			double W = width * scale;
			
			shapes.add(new Line2D.Double( x, y, x, y+5*H/36 ) );
			shapes.add(new Line2D.Double( x, y+5*H/36, x-W/4, y+7 *H/36) );
			shapes.add(new Line2D.Double( x-W/4, y+7*H/36, x+W/4, y+11*H/36 ) );
			shapes.add(new Line2D.Double( x+W/4, y+11*H/36, x-W/4, y+15*H/36 ) );
			shapes.add(new Line2D.Double( x-W/4, y+15*H/36, x+W/4, y+19*H/36 ) );
			shapes.add(new Line2D.Double( x+W/4, y+19*H/36, x-W/4, y+23*H/36 ) );
			shapes.add(new Line2D.Double( x-W/4, y+23*H/36, x+W/4, y+27*H/36 ) );
			shapes.add(new Line2D.Double( x+W/4, y+27*H/36, x, y+29*H/36 ) );
			shapes.add(new Line2D.Double( x, y+29*H/36, x, y+32*H/36 ) );
			shapes.add(new Line2D.Double( x-W/2, y+32*H/36, x+W/2, y+32*H/36 ) );
			for(int i = 0; i < 6 ; i++)
				shapes.add(new Line2D.Double( x - W/2 + (i+1)*(W/6), y + 32*H/36, x - W/2 + i*(W/6), y + H ));
			
			return shapes;
		}
		
	//*****************************************************************************
		
		/**
		 * Returns the draw bounds in device units.
		 *
		 * @return the draw bounds
		 */
		 public Rectangle getBounds() {
			 
			 int x = this.getLocation().x;
			 int y = this.getLocation().y;
			 int width = this.getSize().width;
			 int height = this.getSize().height;
			 double scale = this.getScale();
			 
			 int W = (int)(width * scale);
			 int H = (int)(width * scale);
			 int h = (int)(height/6 * scale);
			 return new Rectangle((int)(x - W/2), y, W, H - h);
		 }
		 
	}
	
//*****************************************************************************
//*****************************************************************************
	
	public static class Rz extends SpringDraw {
	
	//*****************************************************************************
		
		public Rz() {
			this(new Point(0, 0), 0);
		}
		
	//*****************************************************************************
		
		public Rz(Point loc) {
			this(loc, 0);
		}
		
	//*****************************************************************************
		
		public Rz(Point loc, double theta) {
			this(loc, theta, null);
		}
		
	//*****************************************************************************
		
		public Rz(Point loc, double theta, Object represents) {
			this.setLocation(loc);
			this.setAngle(theta);
			this.setRepresents(represents);
			this.setSize(new Dimension(20, 20));
		}
		
	//*****************************************************************************
		
		public Vector<Object> getShapes() {
			
			Vector<Object> shapes = new Vector<Object>();
			
			int x = this.getLocation().x;
			int y = this.getLocation().y;
			int width = this.getSize().width;
			int height = this.getSize().height;
			double scale = this.getScale();
			
			double h = height/5 * scale;
			double H = height/2 * scale;
			double W = width/2 * scale;
			
			double x1 = x;
			double y1 = y +H*(- 0.875);
			double cx1 = x +W*( 0.36);
			double cy1 = y +H*(- 0.907);
			double cx2 = x +W*( 0.88);
			double cy2 = y +H*(- 0.71);
			double x2 = x +W*( 1.0);
			double y2 = y;
			shapes.add( new CubicCurve2D.Double(x1, y1, cx1, cy1, cx2, cy2, x2, y2) ); //8
			cx1 = x +W*(- 0.797);
			cy1 = y +H*(- 0.45);
			cx2 = x +W*(- 0.45);
			cy2 = y +H*(- 0.834);
			x2 = x +W*(- 0.75);
			shapes.add( new CubicCurve2D.Double(x2, y2, cx1, cy1, cx2, cy2, x1, y1) ); //7
			y1 = y +H*(+ 0.625);
			cx1 = x +W*(- 0.31);
			cy1 = y +H*(+ 0.664);
			cx2 = x +W*(- 0.703);
			cy2 = y +H*(+ 0.45);
			shapes.add( new CubicCurve2D.Double(x1, y1, cx1, cy1, cx2, cy2, x2, y2) ); //6
			cx1 = x +W*(+ 0.549);
			cy1 = y +H*(+ 0.31);
			cx2 = x +W*(+ 0.31);
			cy2 = y +H*(+ 0.586);
			x2 = x +W*(0.5);
			shapes.add( new CubicCurve2D.Double(x2, y2, cx1, cy1, cx2, cy2, x1, y1) ); //5
			y1 = y +H*(- 0.375);
			cx1 = x +W*(+ 0.24);
			cy1 = y +H*(- 0.425);
			cx2 = x +W*(+ 0.461);
			cy2 = y +H*(- 0.25);
			shapes.add( new CubicCurve2D.Double(x1, y1, cx1, cy1, cx2, cy2, x2, y2) ); //4
			cx1 = x +W*(- 0.3);
			cy1 = y +H*(- 0.16);
			cx2 = x +W*(- 0.19);
			cy2 = y +H*(- 0.335);
			x2 = x +W*(- 0.25);
			shapes.add( new CubicCurve2D.Double(x2, y2, cx1, cy1, cx2, cy2, x1, y1) ); //3
			y1 = y +H*(+ 0.125);
			cx1 = x +W*(- 0.08);
			cy1 = y +H*(+ 0.175);
			cx2 = x +W*(- 0.209);
			cy2 = y +H*(+ 0.13);
			shapes.add( new CubicCurve2D.Double(x1, y1, cx1, cy1, cx2, cy2, x2, y2) ); //2
			cx1 = x +W*(+ 0.068);
			cy1 = y +H*(+ 0.012);
			cx2 = x +W*(+ 0.053);
			cy2 = y +H*(+ 0.092);
			x2 = x;
			shapes.add( new CubicCurve2D.Double(x2, y2, cx1, cy1, cx2, cy2, x1, y1) ); //1
			
			shapes.add(new Line2D.Double(x + W , y , x + (3*W/2), y ) );
			shapes.add(new Line2D.Double(x + (3*W/2), y - H, x + (3*W/2), y + H ) );
			for(int i = -1; i < (H/h+1) ; i++)
				shapes.add(new Line2D.Double(x + (3*W/2), y - H/2 + i*h,x + (3*W/2) + h, y - H/2 + ((i + 1) * h)));
			
			return shapes;
		}
		
	//*****************************************************************************
		
		/**
		 * Returns the draw bounds in device units.
		 *
		 * @return the draw bounds
		 */
		 public Rectangle getBounds() {
			 
			 int x = this.getLocation().x;
			 int y = this.getLocation().y;
			 int width = this.getSize().width;
			 int height = this.getSize().height;
			 double scale = this.getScale();
			 
			 int W = (int)(width * scale);
			 int H = (int)(width * scale);
			 int h = (int)(height/6 * scale);
			 return new Rectangle((int)(x - W/2), y, W, H - h);
		 }
		 
	}
	
//*****************************************************************************
//*****************************************************************************
}
